/*
* Copyright (c) 2008 Thierry Coppey, EPFL
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Thierry Coppey nor EPFL, nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THIERRY COPPEY AND EPFL ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THIERRY COPPEY OR EPFL BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#import "Dig.h"

#define BUFSIZE 2048

void* dig_thr(void* arg) {
	Dig* d=(Dig*)arg;
	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
	char q[128],s[128],v[32]; int n,f,p[2],t=[d type];
	s[0]='@'; strlcpy(s+1,[[d serv] UTF8String],127); strlcpy(v,[[d typeName] UTF8String],32);
	do { strlcpy(q,[[d query] UTF8String],128); usleep(750*1000); } while (strcmp(q,[[d query] UTF8String]));
	if (!q[0]) goto cleanup; pipe(p);
	switch(f=fork()) {
		case -1: close(p[1]); goto cleanup;
		case  0: dup2(p[1],1); dup2(p[1],2); close(p[1]); close(p[0]);
			if (s[1]) switch(t) {
				case 0: execlp("dig","dig",s,"-q",q,"-t","ANY",0);
				case 1: execlp("dig","dig",s,"-x",q,"+nocmd",0);
				default: execlp("dig","dig",s,"-q",q,"-t",v,"+nocmd",0); 
			} else switch(t) {
				case 0: execlp("dig","dig","-q",q,"-t","ANY",0);
				case 1: execlp("dig","dig","-x",q,"+nocmd",0);
				default: execlp("dig","dig","-q",q,"-t",v,"+nocmd",0); 
			}
			_exit(1);
	}
	waitpid(f,0,0); close(p[1]);
	NSMutableString *r=[[NSMutableString alloc] init]; char buf[BUFSIZE]; memset(buf,0,BUFSIZE);
	while (n=read(p[0],buf,BUFSIZE-1)) { [r appendString:[NSString stringWithUTF8String:buf]]; memset(buf,0,n); }
	[d setResult:r]; cleanup: close(p[0]); [d setTh:false]; [pool release]; pthread_exit(0); return 0;
}

@implementation Dig
- (id)init { if (self=[super init]) { has_th=false; last=[NSString stringWithString:@""]; } return self; }
- (void)dealloc { [last release]; [super dealloc]; }

- (NSString*) query { return [search stringValue]; }
- (NSString*) serv { return [server stringValue]; };
- (NSString*) typeName { return [[type selectedItem] title];  }
- (int) type { return [type indexOfSelectedItem]; };


- (void) setResult:(NSString*)text { [output setString:text]; }
- (void) setTh:(bool)v { has_th=v; }

- (IBAction) search:(id)Sender {
	NSString* v=[NSString stringWithFormat:@"%@:%@:%d",[search stringValue],[server stringValue],[type indexOfSelectedItem]];
	if ([v isEqualToString:last]) return; [last release]; last=[v retain];
	if ([[search stringValue] isEqualToString:@""]) { [drawer close]; return; } if (has_th) return;
	[output setString:@""]; [drawer open]; pthread_create(&dig_th,nil,dig_thr,self); has_th=true;
}

@end
